package com.hwy;

import com.hwy.utils.ContentUtil;
import com.hwy.utils.DownloadUtil;
import com.hwy.utils.HttpClientUtil;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import java.io.File;
import java.io.InputStream;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * 启动类
 */
public class Application {
    // 目录url
    private static final String MENU_URL = "https://www.cartoonmad.com/comic/5264.html";
    // 漫画页面url前缀
    private static final String CARTOON_PAGE_URL_PREFIX;
    // 漫画下载文件夹地址
    private static final String DOWNLOAD_DIR_PATH = "e:/哥布林杀手/";
    // 自定义线程池
    private static final ThreadPoolExecutor EXECUTOR;

    static {
        // 获取漫画统一前缀
        CARTOON_PAGE_URL_PREFIX = String.format("https://www.cartoonmad.com/5e585/%s/", ContentUtil.getCartoonNum(MENU_URL));
        // 初始化线程池
        EXECUTOR = new ThreadPoolExecutor(
                10,
                20,
                100000,
                TimeUnit.SECONDS,
                new LinkedBlockingQueue<>(),
                Executors.defaultThreadFactory(),
                (r, executor) -> {
                    //不抛弃任务，加入到等待队列
                    try {
                        executor.getQueue().put(r);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
        );
    }

    public static void main(String[] args) {
        // 获取目录url对应的html内容
        String menuContent = HttpClientUtil.getHtmlContentByGet(MENU_URL);
        // 创建文件夹
        DownloadUtil.createDir(DOWNLOAD_DIR_PATH);
        // html内容解析为doc对象
        Document document = Jsoup.parse(menuContent);
        // 获取id为info的标签（有两个，只需要第二个）
        Element info = document.select("#info").get(1);
        // 话信息
        Elements chapterInfoList = info.select("tbody").select("a");
        // 页信息
        Elements pageInfoList = info.select("tbody").select("font");
        // 合并数据
        LinkedHashMap<String, String> downloadInfoMap = new LinkedHashMap<>(1024);
        // 用于拼接字符串
        StringBuilder downloadFilePath = new StringBuilder();
        StringBuilder imageUrl = new StringBuilder();
        for (int i = 0; i < chapterInfoList.size(); i++) {
            // 话的数字
            String chapterNum = ContentUtil.getNum(chapterInfoList.get(i).text());
            // 页的数字
            String pageNum = ContentUtil.getNum(pageInfoList.get(i).text());
            int page = Integer.parseInt(pageNum);
            // 循环取每一页的数据
            for (int j = 1; j <= page; j++) {
                // 拼接本地下载地址
                downloadFilePath
                        .append(DOWNLOAD_DIR_PATH)
                        .append(chapterNum)
                        .append("-")
                        .append(String.format("%03d", j))
                        .append(".jpg");
                // 拼接图片url地址
                imageUrl
                        .append(CARTOON_PAGE_URL_PREFIX)
                        .append(chapterNum)
                        .append("/")
                        .append(String.format("%03d", j))
                        .append(".jpg");
                downloadInfoMap.put(downloadFilePath.toString(), imageUrl.toString());
                // 重置StringBuilder
                downloadFilePath.setLength(0);
                imageUrl.setLength(0);
            }
            // 创建任务
            createTask(downloadInfoMap);
            downloadInfoMap = new LinkedHashMap<>();
        }
        // 关闭线程池
        EXECUTOR.shutdown();
    }

    /**
     * 创建任务
     */
    private static void createTask(Map<String, String> map) {
        EXECUTOR.execute(() -> {
            for (Map.Entry<String, String> entry : map.entrySet()) {
                String filePath = entry.getKey();
                File file = new File(filePath);
                if (!file.exists()) {
                    System.out.println();
                    InputStream inputStream = HttpClientUtil.getResponseInputStreamByGet(entry.getValue());
                    DownloadUtil.createFileByInputStream(inputStream, filePath);
                }
                file = null;
            }
        });
    }
}
